<template>
  <el-dialog :close-on-click-modal="false" :title="form.id ? $t('common.editBtn') : $t('common.addBtn')" width="600"
             draggable v-model="visible">
   <el-form :model="form"  ref="dataFormRef" label-width="100px" :rules="dataRules" v-loading="loading">
               <el-form-item :label="$t('aigcModel.modelType')" prop="modelType">
                   <el-select v-model="form.modelType" :placeholder="$t('aigcModel.inputModelTypeTip')">
                       <el-option v-for="item in LLM_MODEL_TYPE" :key="item.value" :label="item.label" :value="item.value"></el-option>
                   </el-select>
               </el-form-item>
               <el-form-item :label="$t('aigcModel.name')" prop="name">
                   <el-input v-model="form.name" :placeholder="$t('aigcModel.inputNameTip')" clearable ></el-input>
               </el-form-item>
              <el-form-item :label="$t('aigcModel.provider')" prop="provider">
                  <el-select v-model="form.provider" :placeholder="$t('aigcModel.inputProviderTip')">
                     <el-option v-for="item in LLM_PROVIDER" :key="item.value" :label="item.label" :value="item.value"></el-option>
                 </el-select>
              </el-form-item>
               <el-form-item :label="$t('aigcModel.modelName')" prop="modelName">
                   <el-select v-model="form.modelName" :placeholder="$t('aigcModel.inputModelNameTip')">
                        <el-option v-for="item in llmModels" :key="item.value" :label="item.label" :value="item.value"></el-option>
                    </el-select>
               </el-form-item>
                <el-form-item :label="$t('aigcModel.modelVersion')" prop="modelVersion">
                   <el-input v-model="form.modelVersion" :placeholder="$t('aigcModel.inputModelVersionTip')" clearable ></el-input>
               </el-form-item>

               <el-form-item :label="$t('aigcModel.baseUrl')" prop="baseUrl">
                   <el-input v-model="form.baseUrl" :placeholder="$t('aigcModel.inputBaseUrlTip')" clearable ></el-input>
               </el-form-item>
               <el-form-item :label="$t('aigcModel.apiKey')" prop="apiKey">
                   <el-input v-model="form.apiKey" :placeholder="$t('aigcModel.inputApiKeyTip')" clearable ></el-input>
               </el-form-item>
                <el-form-item :label="$t('aigcModel.secretKey')" prop="secretKey">
                   <el-input v-model="form.secretKey" :placeholder="$t('aigcModel.inputSecretKeyTip')" readonly clearable >
                       <template #append>
                            <el-button type="primary" @click="generateSecretKey">{{ $t('aigcModel.generateBtn') }}</el-button>
                       </template>
                   </el-input>
               </el-form-item>
               <el-form-item :label="$t('aigcModel.responseLimit')" prop="responseLimit" v-if="form.modelType==='1'">
                   <el-slider v-model="form.responseLimit" :step:="512" :min="0" :max="8192" show-stops/>
               </el-form-item>
               <el-form-item :label="$t('aigcModel.temperature')" prop="temperature"  v-if="form.modelType==='1'">
                   <DecimalSlider v-model="form.temperature" :min="0.0" :max="2.0" :step="0.1"/>
               </el-form-item>
                <el-form-item :label="$t('aigcModel.topP')" prop="topP"  v-if="form.modelType==='1'">
                   <DecimalSlider v-model="form.topP" :step:="0.1" :min="0.0" :max="1.0"/>
               </el-form-item>

               <el-form-item :label="$t('aigcModel.dimension')" prop="dimension" v-if="form.modelType==='2'">
                  <el-input type="number" v-model="form.dimension" :placeholder="$t('aigcModel.inputDimensionTip')" clearable/>
               </el-form-item>

                <el-form-item :label="$t('aigcModel.imageSize')" prop="imageSize" v-if="form.modelType==='3'">
                  <el-select v-model="form.imageSize" :placeholder="$t('aigcModel.inputImageSizeTip')">
                    <el-option v-for="item in LLM_IMAGE_SIZE" :key="item.value" :label="item.label" :value="item.value"></el-option>
                  </el-select>
                </el-form-item>
                <el-form-item :label="$t('aigcModel.imageQuality')" prop="imageQuality" v-if="form.modelType==='3'">
                  <el-select v-model="form.imageQuality" :placeholder="$t('aigcModel.inputImageQualityTip')">
                      <el-option v-for="item in LLM_IMAGE_QUANTITY" :key="item.value" :label="item.label" :value="item.value"></el-option>
                  </el-select>
                </el-form-item>
                 <el-form-item :label="$t('aigcModel.imageStyle')" prop="imageStyle" v-if="form.modelType==='3'">
                   <el-select v-model="form.imageStyle" :placeholder="$t('aigcModel.inputImageStyleTip')">
                        <el-option v-for="item in LLM_IMAGE_STYLE" :key="item.value" :label="item.label" :value="item.value"></el-option>
                   </el-select>
                </el-form-item>

               <el-form-item :label="$t('aigcModel.remark')" prop="remark">
                   <el-input type="textarea" :rows="5" v-model="form.remark" :placeholder="$t('aigcModel.inputRemarkTip')" clearable/>
               </el-form-item>
           </el-form>

         <template #footer>
			<span class="dialog-footer">
				<el-button @click="visible=false">{{ $t('common.cancelButtonText') }}</el-button>
				<el-button @click="onSubmit" type="primary" :disabled="loading">{{ $t('common.confirmButtonText') }}</el-button>
			</span>
        </template>
  </el-dialog>
</template>

<script lang="ts" name="aigcModelChatDialog" setup>
import { useI18n } from 'vue-i18n';
import { addObj, getObj, putObj } from '/@/api/aigc/model';
import { findModelList, findProviderList } from "/@/api/aigc/providerModel";
import DecimalSlider from '/@/components/Slider/index.vue';
import { useDict } from "/@/hooks/dict";
import { useMessage } from '/@/hooks/message';
import { decrypt, encrypt, generateKey } from '/@/utils/keyTool';
const {LLM_MODEL_TYPE,LLM_PROVIDER,LLM_PROVIDER_URL,LLM_IMAGE_SIZE,LLM_IMAGE_QUANTITY,LLM_IMAGE_STYLE} = useDict('LLM_MODEL_TYPE','LLM_PROVIDER','LLM_PROVIDER_URL','LLM_IMAGE_SIZE','LLM_IMAGE_QUANTITY','LLM_IMAGE_STYLE');

// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);

const {t} = useI18n();

// 定义变量内容
const dataFormRef = ref();
const visible = ref(false);
const loading = ref(false);
//供应商
const llmProviders=ref<DictItem[]>([]);
// 提交表单数据
const form = reactive({
      id:'',
      name:'',
      modelName:'',
      modelVersion:'',
      modelType:'1',
      provider:'',
      baseUrl:'',
      apiKey:'',
      apiKeyEncrypt:'',
      secretKey:'',
      responseLimit:1024,
      temperature:0.7,
      topP:0.7,
      prompt:'',
      remark:'',
      dimension:1,
      imageSize:'',
      imageQuality:'',
      imageStyle:'',
});

// 定义校验规则
const dataRules = ref({
    name: [
        {required: true, message: '别名不能为空', trigger: 'blur'},
        {min: 3, max: 50, message: '长度在 3 到 50 个字符', trigger: 'blur'},
    ],
    modelName: [
      {required: true, message: '模型名称不能为空', trigger: 'blur'},
      {min: 1, max: 50, message: '长度在 3 到 50 个字符', trigger: 'blur'},
    ],
    modelType: [
      {required: true, message: '模型类型不能为空', trigger: 'blur'},
    ],
    provider: [
      {required: true, message: '供应商不能为空', trigger: 'blur'},
    ],
    baseUrl: [
      {required: true, message: '模型地址不能为空', trigger: 'blur'},
    ],
    apiKey: [
      {required: true, message: 'apiKey不能为空', trigger: 'blur'},
    ],
});

// 打开弹窗
const openDialog = (id: string) => {
  visible.value = true;
  form.id = '';

  nextTick(() => {
    dataFormRef.value.resetFields();
  });

  // 获取信息
  if (id) {
    form.id = id;
    getData(id);
  }
   // 初始化供应商列表
  initProviderList(form.modelType);
  // 更新供应商列表
  initFindModelList(form.modelType,form.provider);
};

 // 初始化供应商列表
const initProviderList=(modelType:string)=>{
     llmProviders.value=[];
     findProviderList(modelType).then((res:any)=>{
        if(res.success){
           //供应商赋值
           res.data.forEach((item:any)=>{
               let provider = item.provider;
               let providerName = item.providerName;
               let providerDict=<DictItem>{
                   label:providerName,
                   value:provider,
               };
               llmProviders.value.push(providerDict);
               //默认赋值
               if(form.provider==''||form.provider===undefined){
                   form.provider = provider;
               }
           });
       }
     });
}

//供应商模型
const llmModels=ref<DictItem[]>([]);
//获取供应商信息
const initFindModelList=(modelType:string,provider:string)=>{
    findModelList(modelType,provider).then((res:any)=>{
        if(res.success){
            llmModels.value=[];
            //供应商赋值
            res.data.forEach((item:any)=>{
                let model = item.modelName;
                let modelDict=<DictItem>{
                    label:model,
                    value:model,
                };
                llmModels.value.push(modelDict);
            });
        }
    });
}
//初始化providerBaseURL
const initProviderBaseUrl=(provider:string)=>{
  const provideURLDict= LLM_PROVIDER_URL.value.find((item:DictItem)=>item.value===provider);
  if(provideURLDict){
    if(form.baseUrl===""||form.baseUrl===undefined){
      form.baseUrl=provideURLDict.label;
    }
  }
}
//监听模型类型变化，更新供应商列表
watch(()=>form.modelType,(newVal,oldVal)=>{
    if(newVal!==oldVal&&newVal!==''){
        form.provider='';
        initProviderList(form.modelType);
        initFindModelList(newVal,form.provider);
    }
});
//监听模型供应商变化，更新供应商列表
watch(()=>form.provider,(newVal,oldVal)=>{
    if(newVal!==oldVal&&newVal!==''){
        //初始化加载
        if(newVal!=='' && oldVal!==''){
          form.modelName='';
          form.baseUrl='';
        }
        initFindModelList(form.modelType,newVal);
        //初始化baseURL地址
        initProviderBaseUrl(newVal);
    }
});
// 提交
const onSubmit = async () => {
  const valid = await dataFormRef.value.validate().catch(() => {
  });
  if (!valid) return false;

  try {
    loading.value = true;
    //更新加密密钥
    if(form.apiKey&&form.apiKey!==""&&form.apiKey!=='******'&&form.secretKey&&form.secretKey!==""){
        let apiKey=form.apiKey;
        let secretKey = form.secretKey;
        form.apiKeyEncrypt = encrypt(apiKey,secretKey);
        form.apiKey = form.apiKeyEncrypt;
    }
    form.id ? await putObj(form) : await addObj(form);
    useMessage().success(t(form.id ? 'common.editSuccessText' : 'common.addSuccessText'));
    visible.value = false;
    emit('refresh');
  } catch (err: any) {
    useMessage().error(err.msg);
  } finally {
    loading.value = false;
  }
};

// 初始化数据
const getData = (id: string) => {
  getObj(id).then((res: any) => {
    Object.assign(form, res.data);
    //解密
    if(form.apiKey&&form.apiKey!==""&&form.apiKey!=='******'&&form.secretKey&&form.secretKey!==""){
        let apiKey=form.apiKey;
        let secretKey = form.secretKey;
        form.apiKey=decrypt(form.apiKey,secretKey);
    }
  });
};
//生成随机密钥
const generateSecretKey=()=>{
    form.secretKey = generateKey(16);
}
// 暴露变量
defineExpose({
  openDialog,
});
</script>